home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / dir / browser2.41 / c / tiny_for.c < prev    next >
C/C++ Source or Header  |  1993-03-14  |  3KB  |  131 lines

  1. /*
  2.  *    For.c - Copyright © 1992 by Devil's child.
  3.  *
  4.  *    Created:    30 Mar 1992  18:26:36
  5.  *    Modified:    14 Mar 1993  12:03:47
  6.  *
  7.  *    Make>> sc <file>.c
  8.  *    Make>> slink LIB:cs.o <file>.o SC SD ND BATCH NOICONS TO <file> LIB LIB:Startup.lib LIB:String.lib
  9.  *    Make>> Protect <file> P ADD
  10.  */
  11.  
  12.  
  13. extern struct ExecBase *SysBase;
  14.  
  15.  
  16. char *Template = "Args/M,ALL/S,DONTFAIL/S,DO/K/A/F";
  17. char *CliHelp = "\
  18. For V1.0 © 1992 by S.R. & P.C.\n\
  19. Usage: For <Files | Pattern> [ALL] DO Command [args] [,Command [args] [,...]]\n\
  20. For executes a list of commands for each file given,\n\
  21. replacing each %% in commands with current file name.\n\
  22. ALL: Recursively descends in subirectories.\n\
  23. DONTFAIL: Continue even if a command fails.\n";
  24.  
  25.  
  26. #define Arg_All            1
  27. #define Arg_DontFail    2
  28. #define Arg_Command        3
  29.  
  30. #define MAX_PATHLEN        256
  31.  
  32.  
  33. BOOL CheckedRun(char *CmdBuf, long *RC)
  34. {
  35.     if ((*RC = SystemTags(CmdBuf, TAG_DONE)) > Cli()->cli_FailLevel) {
  36.         Printf("ForEach: Command '%s' Failed.\n", CmdBuf);
  37.         return FALSE;
  38.     }
  39.     else
  40.         return TRUE;
  41. }
  42.  
  43.  
  44. /*
  45.  *    Parse a line that may contain comas. Backslash ('\') is the override char.
  46.  */
  47.  
  48. static void __inline ParseCmdLine(char *cmd)
  49. {
  50.     char *s,*d,c;
  51.  
  52.     s = d = cmd;
  53.     while (c = *d++ = *s++) {
  54.         if (c == '\\')
  55.             *(d-1) = *s++;
  56.         else if (c == ',')
  57.             *(d-1) = '\n';
  58.     }
  59. }
  60.  
  61.  
  62. long Main(char *argv[], struct WBStartup *WBenchMsg)
  63. {
  64.     char CmdBuf[512], Fmt[512], ArgBuf[256];
  65.     char **Args, *s;
  66.     struct AnchorPath *AP;
  67.     long RC = 20, len;
  68.     BOOL Found = FALSE, Abort = FALSE;
  69.  
  70.     strcpy(Fmt, argv[Arg_Command]);
  71.     if ((len = strlen(Fmt)) == 0)
  72.         return 10;
  73.     ParseCmdLine(Fmt);    /* Replace , by \n to separate commands */
  74.     s = Fmt;
  75.     while(*s) {
  76.         if (*s == '%' && *(s+1) == '%') {
  77.             *(s+1) = 's';
  78.             Found = TRUE;
  79.         }
  80.         s++;
  81.     }
  82.     if (!Found)
  83.         strcpy(&Fmt[len], " %s");
  84.  
  85.     if (Args = (char **)argv[0]) {
  86.         if (AP = AllocVec(sizeof(struct AnchorPath)+MAX_PATHLEN, MEMF_PUBLIC|MEMF_CLEAR)) {
  87.             while (!Abort && *Args) {
  88.                 LONG MatchErr;
  89.  
  90.                 AP->ap_BreakBits = SIGBREAKF_CTRL_C;    /* Break on these bits    */
  91.                 AP->ap_Strlen = MAX_PATHLEN;
  92.                 AP->ap_Flags = (argv[Arg_All]) ? APF_DODOT : APF_DODOT|APF_DOWILD;    /* allow convertion of '.' to CurrentDir */
  93.                 MatchErr = MatchFirst(*Args, AP);
  94.                 while (!MatchErr) {
  95.                     if (argv[Arg_All] && AP->ap_Info.fib_DirEntryType > 0) {
  96.                         if (!(AP->ap_Flags & APF_DIDDIR))
  97.                             AP->ap_Flags |= APF_DODIR;
  98.                         /* clear the completed directory flag */
  99.                         AP->ap_Flags &= ~APF_DIDDIR;
  100.                     }
  101.                     else {
  102.                         s = AP->ap_Buf;
  103.                         SPrintf(ArgBuf, StrChr(s, ' ') ? "\"%s\"" : "%s", s);
  104.                         /* Allow 5 %% in cmd */
  105.                         SPrintf(CmdBuf, Fmt, ArgBuf, ArgBuf, ArgBuf, ArgBuf, ArgBuf);
  106.                         if (!CheckedRun(CmdBuf, &RC) && !argv[Arg_DontFail]) {
  107.                             Abort = TRUE;
  108.                             break;
  109.                         }
  110.                     }
  111.                     MatchErr = MatchNext(AP);
  112.                 }
  113.                 MatchEnd(AP);    /* This absolutely, positively must be called, all of the time. */
  114.                 if (!Abort && MatchErr != ERROR_NO_MORE_ENTRIES) {
  115.                     PrintFault(MatchErr, NULL);
  116.                     RC = 20;
  117.                     break;
  118.                 }
  119.                 Args++;
  120.             }
  121.             FreeVec(AP);
  122.         }
  123.     }
  124.     else {
  125.         SPrintf(CmdBuf, Fmt, "", "", "", "", "");    /* Always remove %%'s from command line */
  126.         CheckedRun(CmdBuf, &RC);
  127.     }
  128.     return RC;
  129. }
  130.  
  131.